package cn.datawin.crule;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import cn.datawin.Builder;

public class ServiceBuilder implements Builder {

	public static Cache<String, Object> cache = CacheBuilder.newBuilder().maximumSize(300).build();

	private static ServiceBuilder serviceBuilder = new ServiceBuilder();

	Logger log = LoggerFactory.getLogger(getClass());

	private ServiceBuilder() {
	}

	public static ServiceBuilder getInstance() {
		return serviceBuilder;
	}

	@Override
	public <T> T build(Class<T> _class) {
		T t = newInstance(_class);
		cache.put(_class.getName(), t);
		return t;
	}

	public <T> T newInstance(Class<T> _class) {
		try {
			return _class.newInstance();
		} catch (Exception e) {
			log.error("newInstance", e);
			return null;
		}
	}

	@Override
	public <T> void destory(Class<T> _class) {
		cache.invalidate(_class.getName());
	}

	@Override
	public <T> T getCache(final Class<T> _class) {
		try {
			return _class.cast(cache.get(_class.getName(), new Callable<Object>() {
				@Override
				public Object call() throws Exception {
					return newInstance(_class);
				}
			}));
		} catch (ExecutionException e) {
			log.error("getCache", e);
			return null;
		}
	}

}
